﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using RyanLam.NET.Core;

[assembly: WebResource("RyanLam.NET.Templates.AdminControl.Images.menu-open-arrow.png", "image/png")]
namespace RyanLam.NET.Templates.AdminControl.Menu
{
    [
    DefaultProperty("Text"),
    ParseChildren(true),
    PersistChildren(false),
    ToolboxData("<{0}:ACMenu runat=\"server\"></{0}:ACMenu>")
    ]
    public class ACMenu : CompositeControl
    {
        #region Private Member Variables
        private int parentID;
        private Core.ITemplates.EnumTrueOrFalse reloadData;
        private Core.ITemplates.EnumTrueOrFalse checkLoginPermission;
        private int currentMainMenuID = 1;
        private int currentSubMenuID = 1;
        private static int currentLevel = 1;
        #endregion  

        #region Properties

        #region ParentID
        /// <summary>
        /// Menu parent id.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(0),
        Description("Menu parent id."),
        Localizable(true)
        ]
        public int ParentID
        {
            get
            {
                return this.parentID;
            }
            set
            {
                this.parentID = value;
            }
        }
        #endregion

        #region ReloadData
        /// <summary>
        /// Refresh menu's data on memory.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(Core.ITemplates.EnumTrueOrFalse.True),
        Description("Refresh menu's data on memory."),
        Localizable(true)
        ]
        public Core.ITemplates.EnumTrueOrFalse ReloadData
        {
            get
            {
                return this.reloadData;
            }
            set
            {
                this.reloadData = value;
            }
        }
        #endregion

        #region CheckLoginPermission
        /// <summary>
        /// Checking current user login's permission (this process will be based on ASP.NET Membership Built-in).
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(Core.ITemplates.EnumTrueOrFalse.False),
        Description("Checking current user login's permission (this process will be based on ASP.NET Membership Built-in)."),
        Localizable(true)
        ]
        public Core.ITemplates.EnumTrueOrFalse CheckLoginPermission
        {
            get
            {
                return this.checkLoginPermission;
            }
            set
            {
                this.checkLoginPermission = value;
            }
        }
        #endregion

        #region CurrentMainMenuID
        /// <summary>
        /// Selected current main menu id.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(0),
        Description("Selected current main menu id."),
        Localizable(true)
        ]
        public int CurrentMainMenuID
        {
            get
            {
                return this.currentMainMenuID;
            }
            set
            {
                this.currentMainMenuID = value;
            }
        }
        #endregion

        #region CurrentSubMenuID
        /// <summary>
        /// Selected current sub menu id.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(0),
        Description("Selected current sub menu id."),
        Localizable(true)
        ]
        public int CurrentSubMenuID
        {
            get
            {
                return this.currentSubMenuID;
            }
            set
            {
                this.currentSubMenuID = value;
            }
        }
        #endregion            
        
        #region IsReloadData
        /// <summary>
        /// Check if required a reload.
        /// </summary>
        public bool IsReloadData
        {
            get
            {
                if (this.ReloadData == Core.ITemplates.EnumTrueOrFalse.True)
                    return true;
                else if (this.ReloadData == Core.ITemplates.EnumTrueOrFalse.False)
                    return false;
                else
                    return false;
            }
        }
        #endregion

        #region IsCheckLoginPermission
        /// <summary>
        /// Check if required checking on current login user.
        /// </summary>
        public bool IsCheckLoginPermission
        {
            get
            {
                if (this.CheckLoginPermission == Core.ITemplates.EnumTrueOrFalse.True)
                    return true;
                else if (this.CheckLoginPermission == Core.ITemplates.EnumTrueOrFalse.False)
                    return false;
                else
                    return false;
            }
        }
        #endregion


        #endregion

        #region Overrides
        protected override void RenderContents(HtmlTextWriter writer)
        {
            List<Core.Menu.Menu> menus = new List<Core.Menu.Menu>();
            menus = Core.Controllers.GetMenus.GetMenu(this.ParentID, this.IsReloadData, this.IsCheckLoginPermission);
            writer.WriteLine("<nav id='main-nav'>");
            writer.WriteLine("<ul class='container_12'>");
            foreach (Core.Menu.Menu menu in menus)
            {
                writer.WriteLine(String.Format("<li{0}>", menu.CssClass != "" ? String.Format(" class='{0}{1}'", menu.CssClass, this.CurrentMainMenuID == menu.ID ? " current" : String.Empty) : ""));
                HyperLink menuUrl = new HyperLink
                {
                    ID = String.Format("{0}_1_{1}", this.ID, menu.ID),
                    Text = menu.Text,
                    NavigateUrl = menu.NavigationUrl == "" ? "#" : menu.HasChild() ? "#" : menu.NavigationUrl,
                    ToolTip = menu.ToolTip,
                    Target = menu.Target.ToString()
                };
                menuUrl.RenderControl(writer);
                this.WriteMenuChilds(writer, menu);
                writer.WriteLine("</li>");
            }
            writer.WriteLine("</ul>");
            writer.WriteLine("</nav>");
        }
        #endregion

        #region Public Functions
        /// <summary>
        /// Write all child(s) menu belongs to current menu, checking by HasChild() method
        /// </summary>
        /// <param name="writer">The html text wirter which is trying to implement sub(s) menu in.</param>
        /// <param name="parentMenu">The current menu which is going to be parent at sub(s) menu.</param>
        public void WriteMenuChilds(HtmlTextWriter writer, Core.Menu.Menu parentMenu)
        {
            try
            {
                if (parentMenu.HasChild())
                {
                    int clevel = currentLevel;
                    List<Core.Menu.Menu> menus = new List<Core.Menu.Menu>();
                    menus = Core.Controllers.GetMenus.GetMenu(parentMenu.ID, this.IsReloadData, this.IsCheckLoginPermission);
                    writer.WriteLine("<ul>");
                    foreach (Core.Menu.Menu menu in menus)
                    {
                        currentLevel++;
                        // by designed, current menu at second level which is does not need CssClass, and it based on
                        // that menu has child(s) or not, if have child print the tag <li> with class='with-menu'
                        // if not return an regular tag <li>, also open tag <div> with class='menu' on this specific level
                        if (currentLevel == 2)
                            writer.WriteLine(String.Format("<li{0}>", menu.HasChild() ? String.Format(" class='with-menu{0}'", 
                                menu.ID == this.CurrentSubMenuID ? " current" : String.Empty) : 
                                menu.ID == this.CurrentSubMenuID ? " class='current'" : String.Empty));
                        else
                            writer.WriteLine(String.Format("<li{0}>", menu.CssClass != "" ? String.Format(" class='{0}{1}'", 
                                menu.CssClass, menu.ID == this.CurrentSubMenuID ? " current" : String.Empty) : 
                                menu.ID == this.CurrentSubMenuID ? " class='current'" : String.Empty));
                        HyperLink menuUrl = new HyperLink
                        {
                            ID = String.Format("{0}_{1}_{2}", this.ID, currentLevel, menu.ID),
                            Text = menu.Text,
                            NavigateUrl = menu.NavigationUrl == "" ? "#" : menu.HasChild() ? "#" : menu.NavigationUrl,
                            ToolTip = menu.ToolTip,
                            Target = menu.Target.ToString()
                        };
                        menuUrl.RenderControl(writer);
                        // open tag <div class='menu'> for second level menu
                        if (menu.HasChild() && currentLevel == 2)
                        {
                            writer.WriteLine("<div class='menu'>");
                            Image imgOpenChild = new Image
                            {
                                ID =String.Format("{0}_ImgArrow_{1}_{2}", this.ID, currentLevel, menu.ID),
                                ImageUrl = Page.ClientScript.GetWebResourceUrl(typeof(ACMenu), "RyanLam.NET.Templates.AdminControl.Images.menu-open-arrow.png")
                            };
                            imgOpenChild.RenderControl(writer);
                        }
                        this.WriteMenuChilds(writer, menu);
                        // close tag <div> for second level menu
                        if(menu.HasChild() && currentLevel == 2)
                            writer.WriteLine("</div>");
                        writer.WriteLine("</li>");
                        currentLevel = clevel;
                    }
                    writer.WriteLine("</ul>");
                }
            }
            catch (Exception ex) { writer.WriteLine(String.Format("<li>{0}</li>", ex.Message)); }
        }
        #endregion
    }
}
